import { Request, Response } from 'express';
import operLogService from '@/services/system/operLog.service';
import ApiResponse from '@/utils/api/api-response.util';
import { Log, BusinessType } from '@/decorators/Log';
import ExcelUtil from '@/utils/excel/excel.util';
import { getLogger } from '@/utils/logger';
import { AuthRequest } from '@/types';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("operlog-controller");
const logger = getLogger("operlog-controller", {
	console: false,
});

// 业务类型映射
const BusinessTypeMap: Record<number, string> = {
  0: '其它',
  1: '新增',
  2: '修改',
  3: '删除',
  4: '授权',
  5: '导出',
  6: '导入',
  7: '强退',
  8: '生成代码',
  9: '清空数据'
};

// 操作类别映射
const OperatorTypeMap: Record<number, string> = {
  0: '其它',
  1: '后台用户',
  2: '手机端用户'
};

// 获取业务类型文本
const getBusinessTypeText = (type: number): string => {
  return BusinessTypeMap[type] || '未知';
};

// 获取操作类型文本
const getOperatorTypeText = (type: number): string => {
  return OperatorTypeMap[type] || '未知';
};

/**
 * 操作日志控制器
 */
class OperLogController {
  /**
   * 查询操作日志列表
   * @param req 请求对象
   * @param res 响应对象
   */
  public async list(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取操作日志列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 构建查询条件
      const operLog = {
        title: req.query.title as string,
        operName: req.query.operName as string,
        businessType: req.query.businessType ? parseInt(req.query.businessType as string) : undefined,
        status: req.query.status ? parseInt(req.query.status as string) : undefined,
        operIp: req.query.operIp as string,
        params: {
          beginTime: req.query.beginTime as string,
          endTime: req.query.endTime as string
        }
      };

      // 分页查询
      const page = parseInt(req.query.pageNum as string) || 1;
      const pageSize = parseInt(req.query.pageSize as string) || 10;
      
      // 查询操作日志列表
      const { rows, total } = await operLogService.selectOperLogList(operLog, page, pageSize);
      
      // 结果日志
      logger.info("获取操作日志列表成功", {
        response: {
          total,
          count: rows.length,
          page,
          pageSize,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      // 返回分页数据
      ApiResponse.page(res, rows, total, page, pageSize);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取操作日志列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '获取操作日志列表失败');
      }
    }
  }

  /**
   * 导出操作日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '操作日志', businessType: BusinessType.EXPORT })
  public async export(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出操作日志请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      // 构建查询条件
      const operLog = {
        title: req.query.title as string,
        operName: req.query.operName as string,
        businessType: req.query.businessType ? parseInt(req.query.businessType as string) : undefined,
        status: req.query.status ? parseInt(req.query.status as string) : undefined,
        operIp: req.query.operIp as string,
        params: {
          beginTime: req.query.beginTime as string,
          endTime: req.query.endTime as string
        }
      };
      
      // 查询所有操作日志
      const { rows } = await operLogService.selectOperLogList(operLog, 1, Number.MAX_SAFE_INTEGER);
      
      // 定义导出字段配置
      const fields = [
        { header: '日志编号', key: 'operId', width: 10 },
        { header: '操作模块', key: 'title', width: 20 },
        { header: '业务类型', key: 'businessType', width: 15, formatter: (value: number) => getBusinessTypeText(value) },
        { header: '请求方法', key: 'method', width: 15 },
        { header: '请求方式', key: 'requestMethod', width: 10 },
        { header: '操作类别', key: 'operatorType', width: 15, formatter: (value: number) => getOperatorTypeText(value) },
        { header: '操作人员', key: 'operName', width: 15 },
        { header: '部门名称', key: 'deptName', width: 15 },
        { header: '请求地址', key: 'operUrl', width: 30 },
        { header: '操作地址', key: 'operIp', width: 15 },
        { header: '操作地点', key: 'operLocation', width: 20 },
        { header: '请求参数', key: 'operParam', width: 30 },
        { header: '返回参数', key: 'jsonResult', width: 30 },
        { header: '状态', key: 'status', width: 10, formatter: (value: number) => value === 0 ? '正常' : '异常' },
        { header: '错误消息', key: 'errorMsg', width: 30 },
        { header: '操作时间', key: 'operTime', width: 20, type: 'datetime' },
        { header: '消耗时间', key: 'costTime', width: 10, formatter: (value: number) => `${value}毫秒` }
      ];

      // 使用新的 ExcelUtil.exportToResponse 方法导出
      await ExcelUtil.exportToResponse(
        res,
        rows,
        fields,
        `operlog_${Date.now()}`,
        '操作日志'
      );
      
      // 结果日志
      logger.info("导出操作日志成功", {
        response: {
          count: rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出操作日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出操作日志失败', 500);
      }
    }
  }

  /**
   * 删除操作日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '操作日志', businessType: BusinessType.DELETE })
  public async remove(req: AuthRequest, res: Response) {
    try {
      // 获取要删除的日志ID数组
      const operIds = req.params.operIds.split(',').map(id => parseInt(id));
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("删除操作日志请求", {
        params: req.params,
        operIds,
        operator,
      });
      
      // 执行删除操作
      const result = await operLogService.deleteOperLogByIds(operIds);
      
      // 结果日志
      logger.info("删除操作日志成功", {
        response: {
          operIds,
          result,
        },
        operator,
      });
      
      // 返回结果
      ApiResponse.success(res, result, '删除成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除操作日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '删除操作日志失败');
      }
    }
  }

  /**
   * 清空操作日志
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '操作日志', businessType: BusinessType.CLEAN })
  public async clean(req: AuthRequest, res: Response) {
    try {
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("清空操作日志请求", {
        operator,
      });
      
      // 执行清空操作
      await operLogService.cleanOperLog();
      
      // 结果日志
      logger.info("清空操作日志成功", {
        operator,
      });
      
      // 返回结果
      ApiResponse.success(res, null, '清空成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`清空操作日志失败: ${error instanceof Error ? error.message : String(error)}`, {
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '清空操作日志失败');
      }
    }
  }

  /**
   * 获取操作日志详细信息
   * @param req 请求对象
   * @param res 响应对象
   */
  public async getInfo(req: Request, res: Response) {
    try {
      const operId = parseInt(req.params.operId);
      
      // 请求日志
      consoleLogger.info("获取操作日志详情请求", {
        params: req.params,
        operId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 检查operId是否为有效数字
      if (isNaN(operId) || operId <= 0) {
        consoleLogger.warn('获取操作日志详情参数无效', { operId: req.params.operId });
        ApiResponse.error(res, '无效的日志ID', 400);
        return;
      }
      
      // 查询操作日志详情
      const operLog = await operLogService.selectOperLogById(operId);
      
      if (!operLog) {
        consoleLogger.warn('获取操作日志详情 - 日志不存在', { operId });
        ApiResponse.error(res, '日志不存在', 404);
        return;
      }
      
      // 结果日志
      logger.info("获取操作日志详情成功", {
        response: {
          operId,
          title: operLog.title,
          businessType: operLog.businessType,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      // 返回结果
      ApiResponse.success(res, operLog);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取操作日志详情失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '获取操作日志详情失败');
      }
    }
  }
}

export default new OperLogController(); 